package cn.bdqn.sms.system.service.impl;

import cn.bdqn.sms.system.entity.SysMenu;
import cn.bdqn.sms.system.mapper.SysMenuMapper;
import cn.bdqn.sms.system.service.SysMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author zhangpengxiang
 * @description 菜单 业务层
 * @date 2024/11/22
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

    @Resource
    private SysMenuMapper sysMenuMapper;
    /**
     * 根据用户id查询菜单列表
     * @param userId
     * @return
     */
    @Override
    public List<SysMenu> selectMenuListByUserId(Long userId) {
        return sysMenuMapper.selectMenuListByUserId(userId);
    }

    /**
     * 根据用户ID查询菜单树信息
     * @param userId
     * @return
     */
    @Override
    public List<SysMenu> selectMenuTreeByUserId(Long userId) {
        List<SysMenu> menuList = sysMenuMapper.selectMenuTreeByUserId(userId);

        return buildMenuTree(menuList);
    }

    /**
     * 构建菜单树结构，将子菜单封装到父菜单的children集合中
     *
     * @param menuList 原始菜单数据列表
     * @return 构建好的菜单树结构列表
     */
    private List<SysMenu> buildMenuTree(List<SysMenu> menuList) {
        // 用于存储以菜单ID为键，菜单对象为值的映射表，方便快速查找菜单
        Map<Long, SysMenu> menuMap = new HashMap<>();

        // 用于存储根菜单的列表
        List<SysMenu> rootMenus = new ArrayList<>();

        // 第一步：将所有菜单信息存入映射表，并找出根菜单
        for (SysMenu menu : menuList) {
            menuMap.put(menu.getMenuId(), menu);
            if (menu.getParentMenuId() == 0) {
                rootMenus.add(menu);
            }
        }

        // 第二步：遍历所有菜单，为每个非根菜单设置其父菜单的children集合
        for (SysMenu menu : menuList) {
            if (menu.getParentMenuId()!= 0) {
                SysMenu parentMenu = menuMap.get(menu.getParentMenuId());
                parentMenu.getChildren().add(menu);
            }
        }

        return rootMenus;
    }


}
